package cn.edu.hit.core.message;

import com.fasterxml.jackson.databind.JavaType;
import org.apache.commons.lang3.StringUtils;
import cn.edu.hit.core.Document;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 对随机的数据进行生成
 */
public final class Wave2Adapter extends MessageAdapterHelper2<Long> {
    @Override
    public boolean accept(String type) {
        return StringUtils.startsWithIgnoreCase(type, "wave");
    }

    private static JavaType doubleListType = mapper.getTypeFactory().constructParametricType(List.class, Double.TYPE);

//    @Override
//    public Stream<Map> service(Long timestamp) {
//        return configureMap.entrySet().parallelStream().map(entry->{
//            Document result = new Document();
//            String id = entry.getKey();
//            Document configure = (Document) entry.getValue();
//
//            result.put(PORT_ID,id);
//            result.put("portName",configure.getString("portName"));
//
//            String argString = configure.getString(DATA_SOURCE_ARGS);
//            List<Double> value = IntStream.range(0,256)
//                    .mapToDouble(i->generateValue(timestamp+2*i-2,argString))
//                    .boxed()
//                    .collect(Collectors.toList());
//            System.out.println(value);
//            result.put(VALUE,value);
//
//            result.put(TIMESTAMP,timestamp);
//            return result;
//        });
//    }

    @Override
    protected Object getValue(Long timestamp, String id, Document configure) {
        String argString = configure.getString(DATA_SOURCE_ARGS);
        List<Double> value = IntStream.range(0, 256)
                .mapToDouble(i -> generateValue(timestamp + 2 * i - 2, argString))
                .boxed()
                .collect(Collectors.toList());
        return value;
    }

    @Override
    protected Long pretreat(Long timestamp) {
        return timestamp;
    }

    private double generateValue(Long timestamp, String argString) {
        List<Double> value;
        try {
            value = mapper.readValue(argString, doubleListType);
            double avg = getDefault(value, 0, 10);
            double val = avg;
            for (int i = 1; i < value.size(); i += 3) {
                double T = getDefault(value, i, 1);
                T = T < 0.0000001 ? 1 : T;
                double fudu = getDefault(value, i + 1, 2);
                double fi = getDefault(value, i + 2, 0);
                val += fudu * Math.sin(Math.PI * (2 * (timestamp % 1000 / 1000.0) / T) + fi);
            }
            return val;
        } catch (Exception e) {
            e.printStackTrace();
            double val = 10 + 2 * Math.sin(2 * Math.PI * (timestamp % 1000 / 1000.0));
            return val;
        }
    }

    private static double getDefault(List<Double> list, int index, double defaultVal) {
        if (list == null || index < 0 || index >= list.size()) {
            return defaultVal;
        }
        return list.get(index);
    }
}
